/*
 * Copyright (C), 2013, 上海汽车集团股份有限公司
 * FileName: DefaultRouteConfig.java
 * Author:   12010065
 * Date:     2013年10月9日 下午2:03:55
 * Description: //模块目的、功能描述
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.ibm.framework.dal.route.support;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.googlecode.aviator.AviatorEvaluator;
import com.ibm.framework.dal.constants.DalConstants;
import com.ibm.framework.dal.dao.support.sql.FreeMakerParser;
import com.ibm.framework.dal.route.RouteConfig;
import com.ibm.framework.dal.util.DalUtils;

/**
 * 
 * 分库路由默认实现
 * 
 * @author 12010065
 */
public class DefaultRouteConfig implements RouteConfig {
    /**
     * 日志
     */
    private static Logger logger = LoggerFactory.getLogger(DefaultRouteConfig.class);

    /** 规则与数据源的映射表 */
    private Map<String, DataSource> rules;

    /**
     * 分库路由解析方法
     * 
     * @param parameter 分库参数
     * @param 数据源
     * @return 分库数据源
     */
    public DataSource route(Object parameter) {
        if (rules != null && parameter != null) {
            /** 解析分库参数转成数组 */
            Object[] params = DalUtils.convertToObjectArray(parameter);
            /** 遍历分库参数与规则进行匹配 */
            for (Object param : params) {
                logger.debug("route parameter :" + param);
                Map<String, Object> env = new HashMap<String, Object>();
                if (param instanceof Map) {
                    env.put(DalConstants.ROUTE, (Map) param);
                    Iterator<Map.Entry<String, DataSource>> it = rules.entrySet().iterator();
                    /** 遍历分库规则 */
                    while (it.hasNext()) {
                        try {
                            Map.Entry<String, DataSource> entry = it.next();
                            String rule = entry.getKey();
                            /** 支持Freemarker定义的规则 */
                            String expression = FreeMakerParser.process(rule, env);
                            logger.debug("parse express [" + expression + "]");
                            /** 支持aviator定义的规则 */
                            if ((Boolean) AviatorEvaluator.execute(expression, env)) {
                                DataSource dataSource = entry.getValue();
                                logger.debug("current route config : " + rule);
                                logger.debug("current route dataSource : " + dataSource);
                                /** 满足规则对象的数据源 */
                                return dataSource;
                            }
                        } catch (Exception e) {
                            logger.warn("Datasource route exception occurred :{}", e);
                            continue;
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * 设置规则
     * 
     * @param rules 数据源路由规则
     */
    public void setRules(Map<String, DataSource> rules) {
        this.rules = rules;
    }
}
